<?php

class AppController extends Controller {

    var $name = 'app';
    var $components = array('Auth', 'Session', 'RequestHandler', 'Utility');
    var $uses = array();
    var $helpers = array('Ajax', 'Javascript', 'Paginator', 'My', 'Date');
    var $layout = 'main';

    function beforeFilter() {
        $this->header('Cache-Control: no-cache, must-revalidate');
        if ($this->RequestHandler->isAjax()) {
            // ถ้าเป็น code develop ให้ Ajax debug = 1
            if (Configure::read('debug') != 0) {
                Configure::write('debug', 1);
            }
        }
    }

    /**
     * @param string $model ชื่อ model ที่ใช้ในการ paging
     * null ถ้าไม่ได้ระบุ paginate เพิ่มเติม
     */
    function display($model = null) {
        $this->_checkDisplayLimit($model);
    }

    /**
     * แสดงรูปภาพจาก tag image
     * @param string $type
     * @param string $size
     * @param imaage $image
     */
    function image($type, $size, $image) {
        Configure::write('debug', 0);
        $this->header('Content-type: ' . $type);
        $this->header('Content-length: ' . $size);
        $this->header('Accept-Ranges: bytes');
        // file download
        //$this->header('Content-Disposition: attachment; filename='.$image['PictureBarcode']['name']);
        echo $image;
        exit();
    }

    function refresh() {
        $this->layout = 'ajax';

        $params = '';
        // check parameters
        $num = func_num_args();
        for ($i = 0; $i < $num; ++$i) {
            $params .= func_get_arg($i) . '/';
        }
        
        foreach ($this->passedArgs as $key => $value) {
            $params .= $key . ':' . $value . '/';
        }
        
        $this->Session->delete($this->name);

        $this->Session->delete('CustProductSite.paging');

        // เงื่อนไขตอน Search เอาไป print
        $this->Session->delete('Criteria');

        $action = "{$this->name}/display" . ($params != ''? '/' . $params : '');
        $this->redirect($action);
    }

    /**
     * กำหนด limit ในการแสดงแถวข้อมูลในหน้าา display
     * @param string $model ชื่อ model ที่ใช้ในการ paging
     */
    function _checkDisplayLimit($model = null) {
        // ถ้ามีการกำหนด limit แถวในการแสดงข้อมูล (จาก dataCaptionLimitElement)
        $paginate = null;
        if (isset($model)) {
            $paginate = &$this->paginate[$model];
        } else {
            $paginate = &$this->paginate;
        }
        if (isset($this->data['limit'])) {
            if (!empty($this->data['limit'])) {
                $paginate['limit'] = $this->data['limit'];
                $this->Session->write("{$this->name}.limit", $this->data['limit']);
            }
            unset($this->data['limit']);
        } elseif ($this->Session->check("{$this->name}.limit")) {
            $paginate['limit'] = $this->Session->read("{$this->name}.limit");
        }
    }

    /**
     * ตรวจสอบ session ดูว่ามีเงื่อนไขในการ paging อยู่รึไม่
     * ถ้ามีจะอ่านค่ามาเก็บไว้ใน $this->data
     * @return true ถ้ามีข้อมูลการ search เก็บไว้
     */
    function _checkSearchCondition($model) {
        if ($this->Session->check("{$this->name}.{$model}.paging") && empty($this->data)) {
            $this->data = $this->Session->read("{$this->name}.{$model}.paging");
            return true;
        } elseif (isset($this->data[$model]) && !empty($this->data)) {
            $this->clearUnconditionFields();
            $this->Session->delete("{$this->name}.{$model}.conditions");
            $this->Session->write("{$this->name}.{$model}.paging", $this->data);
            return true;
        }
        return false;
    }

    /**
     * clear field ที่ไม่ได้ระบุเงื่อนไข
     * TODO: รองรับแค่ Model 3 ชั้น ถ้ามากกว่า 3 ชั้นจะ ยังไม่ได้ (เปลี่ยน loop เป็น recursive)
     */
    function clearUnconditionFields() {
        foreach ($this->data as $m => &$a) {
            if (is_array($a)) {
                foreach ($a as $k => $v) {
                    if (is_array($v)) {
                        foreach ($v as $k2 => $v2) {
                            if (strlen($this->data[$m][$k][$k2] == 0)) {
                                unset($this->data[$m][$k][$k2]);
                            }
                        }
                    } elseif (strlen($this->data[$m][$k]) == 0) {
                        unset($this->data[$m][$k]);
                    }
                }
            }
        }
        if (isset($this->data['Operand'])) {
            unset($this->data['Operand']);
        }
        if (isset($this->data['Option'])) {
            unset($this->data['Option']);
        }
    }

    /**
     * ตรวจดูว่ามี field ที่ต้องการค้นหาโดย BETWEEN AND หรือไม่
     * ถ้ามีทำการกำหนดค่าให้ถูกต้อง
     * @param <type> $model
     * @param <type> $field
     */
    function _checkBetweenSearch($model, $field) {
        if (isset($this->data[$model][$field . '_start'])) {
            // ถ้ามีทั้ง start และ end แสดงว่ามีการ search เข้ามา
            if (isset($this->data[$model][$field . '_end'])) {
                $this->data[$model][$field . ' BETWEEN ? AND ?'] = array($this->data[$model][$field . '_start'], $this->data[$model][$field . '_end']);
                unset($this->data[$model][$field . '_start']);
                unset($this->data[$model][$field . '_end']);
            } else {
                // มีแต่ start ไม่มี end แสดงว่าไม่ได้เลือกอะไร
                unset($this->data[$model][$field . '_start']);
            }
        } elseif (isset($this->data[$model]) && isset($this->data[$model][$field . '_start']) && is_string($this->data[$model][$field . '_start']) && $this->data[$model][$field . '_start'] === '0') {
            $this->data[$model][$field . ' >= '] = $this->data[$model][$field . '_start'];
            $this->data[$model][$field . ' <= '] = $this->data[$model][$field . '_end'];
            unset($this->data[$model][$field . '_start']);
            unset($this->data[$model][$field . '_end']);
        }
    }

    function _checkCustomerOnHand($model) {
        // เข้าหน้านี้มาครั้งแรก หรือมีการ search
        if (!$this->Session->check("{$this->name}.{$model}.paging") || !empty($this->data)) {
            // แสดงรายการเฉพาะที่ User นี้รับผิดชอบ
            $customers = $this->UserCoH->listCustomerOnHand($this->Auth->user('id'));
            // ถ้าไม่มีการ search customer เข้ามา
            if (empty($this->data[$model]['customer_id'])) {
                $this->data[$model]['customer_id'] = $customers;
            }
        }
    }

    function _checkSupplier($model) {
        // แสดง รายการ เฉพาะ Supplier นี้เท่านั้น
        if (!$this->Session->check("{$this->name}.{$model}.paging") || !empty($this->data)) {
            $this->data[$model]['supplier_id'] = $this->Auth->user('supplier_id');
        }
    }

    /** 
     * กำหนดเงื่อนไขที่จะ search
     * @param type $model
     * @param type $conditions 
     */
    function _checkCustom($model, $conditions) {
        if (!$this->Session->check("{$this->name}.{$model}.paging") || !empty($this->data)) {
            foreach ($conditions as $key => $value) {
                $this->data[$model][$key] = $value;
            }
        }
    }

    function _checkSite($model) {
        // ถ้าเป็น vendor เข้ามา view ดู Customer
        if ($this->Session->read('Auth.User.Extend.from_supplier') == true) {
            $this->_checkSupplier($model);
        }

        if (!$this->Session->check("{$this->name}.{$model}.paging") || !empty($this->data)) {
            $this->data[$model]['site_id'] = $this->Auth->user('site_id');
        }
    }

    function _paging($model, $op = null, $bool = null, $exclusive = null) {
        if ($this->_checkSearchCondition($model)) {
            $conditions = $this->postConditions($this->data, $op, $bool, $exclusive);

            // ถ้าที่หน้า display มีการใช้ paginate ในการระบุเงื่อนไข
            if (!empty($this->paginate[$model]['conditions'])) {
                $conditions = array_merge($this->paginate[$model]['conditions'], $conditions);
                $this->Session->write("{$this->name}.{$model}.conditions", $conditions);
            }
            if (!$this->Session->check("{$this->name}.{$model}.conditions")) {

                // บันทึก conditions ลง session เอาไปใช้กับ neighbour ใน view
                $this->Session->write("{$this->name}.{$model}.conditions", $conditions);
            } else {
                $conditions = $this->Session->read("{$this->name}.{$model}.conditions");
            }
            $this->data = $this->paginate($model, $conditions);
        } else {
            $this->data = $this->paginate($model);
        }
    }

    function inplace_editor(&$model, $field, $id) {
        $this->layout = 'ajax';
        $model->id = $id;
        $value = trim($this->params['form']['value']);

        if (empty($value)) {
            $value = null;
        }

        $display_field = Inflector::humanize($field);
        $data = array();
        $data[$model->name][$field] = $value;
        $data[$model->name]['collector_id'] = $this->Auth->user('id');
        if ($model->save($data)) {
            $this->Session->setFlash("field $display_field = \"{$value}\" save succesfull.", 'flash/ok');
        } else {
            $this->Session->setFlash("field $display_field = \"{$value}\" save fail.", 'flash/fail');
        }

        $this->set('value', $value);
        // view เก็บอยู่ใน element
        $this->viewPath = 'elements';
        $this->render('ajax/inplace_editor');
    }

    function option_list($options) {
        // ใส่ option ว่างรึเปล่า ถ้าเป็น String เข้ามาให้เอาคำนั้นไปแสดง
        if ($this->passedArgs['empty_option'] == "true") {
            $this->set('empty_option', true);
        } elseif ($this->passedArgs['empty_option'] != "false") {
            $this->set('empty_option', $this->passedArgs['empty_option']);
        } else {
            $this->set('empty_option', false);
        }
        $this->set('options', $options);
        $this->viewPath = 'elements';
        $this->render('html/option');
    }

    function autocomplete($options) {
//        // ใส่ option ว่างรึเปล่า ถ้าเป็น String เข้ามาให้เอาคำนั้นไปแสดง
//        if($this->passedArgs['empty_option'] == "true") {
//            $this->set('empty_option', true);
//        } elseif($this->passedArgs['empty_option'] != "false") {
//            $this->set('empty_option', $this->passedArgs['empty_option']);
//        } else {
//            $this->set('empty_option', false);
//        }
        $this->set('options', $options);
        $this->viewPath = 'elements';
        $this->render('html/auto_complete');
    }

    function json_find_by_id($id) {
        $this->layout = 'ajax';
        $this->viewPath = 'elements/ajax';
        $this->RequestHandler->setContent('json');
        $model = $this->uses[0];

        $data = $this->$model->findById($id);

        $this->set('data', $data);
        $this->render('json');
    }

    function json_find_by_field($field, $value) {
        $this->layout = 'ajax';
        $this->viewPath = 'elements/ajax';
        $this->RequestHandler->setContent('json');
        $model = $this->uses[0];

        $method = 'findBy' . Inflector::camelize($field);
        $data = $this->$model->$method($value);

        $this->set('data', $data);
        $this->render('json');
    }

    function popup_search() {
        // เงื่อนไขตอน Search เอาไป print
        $this->Session->delete('Criteria');
        $this->Session->delete('Operand');

        $this->layout = 'popup_search';
        $this->set('showCaption', true);
    }

    /**
     * สำหรับ ITS user เข้ามาดูหน้า print ผ่านทาง email
     */
    function _checkPrintView() {
        if ($this->action == 'print_view') {
            if (isset($this->params['named']['from_email']) && $this->params['named']['from_email'] == true) {
                $this->Auth->allowedActions = array('print_view');
            }
        }
    }

    /**
     * ใช้ร่วมกับ popup_view เป็นส่วนตารางแสดงแถว กรณีที่เป็น Popup แบบ Search ข้อมูลได้
     */
    function popup_paginate() {
        $this->display();
    }

    function array_copy($a, $old_name, $new_name) {
        $n = array();
        foreach ($a as $model => $k) {
            if ($model == $old_name) {
                foreach ($a[$old_name] as $key => $value) {
                    $n[$new_name][$key] = $value;
                }
            } else {
                $n[$model] = $a[$model];
            }
        }
        return $n;
    }

    /**
     * เรียงลำดับรายการใหม่ กรณีลบแถว Index เปลี่ยน เรียงตามลำดับที่ป้อนเข้ามา (key)
     * และลบแถวรายการสุดท้ายออก
     * @param array $data
     */
    function adjustRowIndex(&$data) {
        $keys = array_keys($data);
        array_multisort($keys, $data);

        // ลบรายการแถวที่ว่าง สุดท้ายออก
        $n = count($data);
        unset($data[$n - 1]);
    }

    /**
     * กรณีต้องการเปลี่ยนแปลง user previledge จากหน้า view
     */
    function session_auth_user_field($field, $value) {
        $this->Session->write('Auth.User.' . $field, $value);
    }

    /**
     * กำหนดค่าเริ่มต้นในการส่ง Email
     */
    function _setEmailOptions() {
        $this->Email->smtpOptions = array(
            'port' => '25',
            'username' => 'rt@itsbangkok.com',
            'password' => 'its2008',
            'host' => 'smtpm.csloxinfo.com',
        );
        $this->Email->delivery = 'smtp';
        $this->Email->sendAs = 'html';

        /* Check for SMTP errors. */
        $this->set('smtp-errors', $this->Email->smtpError);
    }

    /**
     * ส่ง Email
     * @param string $from
     * @param mix $emailsTo array หรือ string
     * @param string $subject
     * @param string $template
     * @param boolean $debug
     */
    function sendEmails($from, $emailsTo, $subject, $template, $debug = false) {
        // ถ้าเป็ฯ localhost ไม่ต้องส่ง Email
        if ($_SERVER['SERVER_NAME'] == 'localhost')
            return;
        // ถ้าใส่เป็น String เข้ามาให้แปลงเป็น array
        if (is_string($emailsTo)) {
            $emailTo = $emailsTo;
            $emailsTo = array();
            $emailsTo[] = $emailTo;
        }

        foreach ($emailsTo as $emailTo) {

            // เช็คว่ามีการใส่ , เข้ามาใน emailTo หรือไม่ถ้ามีแตกออกเป็น array
            $e2 = explode(',', $emailTo);

            foreach ($e2 as $e) {
                if (!empty($e)) {
                    $this->_sendEmail($from, $e, $subject, $template, $debug);
                    $this->Email->reset();
                }
            }
        }
    }

    /**
     * ส่ง Email
     * @param string $from email ผู้ส่ง
     * @param string $to email ผู้รับ
     * @param string $subject ชื่อเรื่อง
     * @param string $template ไฟล์ body ข้อความ
     * @param boolean $debug debug หรือไม่
     */
    private function _sendEmail($from, $to, $subject, $template, $debug = false) {
        $this->_setEmailOptions();

        if ($debug == true) {
            $this->Email->delivery = 'debug';
        }

        $this->Email->subject = $subject;
        $this->Email->template = $template;
        $this->Email->from = $from;

        $this->Email->to = $to;

        $this->Email->send();

        if ($debug == true) {
            debug($this->Session->read('Message.email'));
        }
    }

    function excel($fileName) {
        $this->header('Content-type: application/vnd.ms-excel');
        $this->header('Content-Disposition: attachment; filename="' . $fileName . '.xls"');
        $this->layout = 'excel';
        if ($this->data == null) {
            $this->data = array();
        }
    }

    /**
     * template สำหรับ CSV 
     * @param <type> $fileName
     */
    function template($fileName) {
        Configure::write('debug', 0);
        $this->layout = null;
//        $this->header('Content-type: text/csv');
        $this->header('Content-Type: application/vnd.ms-excel');
        $this->header('Content-Disposition: attachment; filename="' . $fileName . '"');
    }

    /**
     * ใช้ สำรับ neighbors ในหน้า view ดู object ข้างเคียงตามเงื่อนไขที่ search ในหน้า display
     * @param <type> $id
     * @param <type> $model
     * @param <type> $options
     */
    function _neighbors($id, $model, $options) {
        $model->id = $id;
        // conditions ตามที่ search ในหน้า display
        $conditions = $this->Session->read("{$this->name}.{$model->name}.conditions");
        $options['conditions'] = $conditions;
        if (!isset($options['contain'])) {
            $options['contain'] = array();
        }
        $this->set('neighbors', $model->find('neighbors', $options));
    }
}

?>